﻿
Option Strict On

Imports System.Net
Imports osi.root.constants
Imports osi.root.utils
Imports osi.root.formation
Imports osi.root.procedure
Imports osi.service.convertor
Imports osi.service.secure
Imports osi.service.zip
Imports osi.service.tcp.constants

Public Class powerpoint
    Shared Sub New()
        assert(IPEndPoint.MinPort >= 0 AndAlso IPEndPoint.MaxPort <= max_uint16)
    End Sub

    Private Shared Function create_zipper(ByVal parameter As String) As zipper
        Dim z As zipper = Nothing
        If zip.create(parameter, z) Then
            assert(Not z Is Nothing)
            Return z
        Else
            Return zip.bypass.instance
        End If
    End Function

    Private Shared Function create_encryptor(ByVal parameter As String) As encryptor
        Dim e As encryptor = Nothing
        If secure.create(parameter, e) Then
            assert(Not e Is Nothing)
            Return e
        Else
            Return secure.encrypt.bypass.instance
        End If
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal host_or_ip As String,
                                  ByVal port As UInt16,
                                  ByVal ipv4 As Boolean,
                                  ByVal connecting_timeout_ms As Int64,
                                  ByVal send_rate_sec As Int32,
                                  ByVal response_timeout_ms As Int64,
                                  ByVal receive_rate_sec As Int32,
                                  ByVal max_connecting As Int32,
                                  ByVal max_connected As Int32,
                                  ByVal no_delay As Boolean,
                                  ByVal max_lifetime_ms As Int64,
                                  ByVal is_outgoing As Boolean,
                                  ByVal enable_keepalive As Boolean,
                                  ByVal first_keepalive_ms As UInt32,
                                  ByVal keepalive_interval_ms As UInt32,
                                  ByVal zipper As String,
                                  ByVal encryptor As String,
                                  ByRef r As powerpoint) As Boolean
        If max_connecting <= 0 OrElse
           max_connected <= 0 Then
            Return False
        ElseIf Not (is_outgoing Xor String.IsNullOrEmpty(host_or_ip)) Then
            Return False
        Else
            If max_connecting > max_connected Then
                max_connecting = max_connected
            End If
            r = New powerpoint(token,
                               host_or_ip,
                               port,
                               ipv4,
                               connecting_timeout_ms,
                               send_rate_sec,
                               response_timeout_ms,
                               receive_rate_sec,
                               max_connecting,
                               max_connected,
                               no_delay,
                               max_lifetime_ms,
                               is_outgoing,
                               enable_keepalive,
                               first_keepalive_ms,
                               keepalive_interval_ms,
                               create_zipper(zipper),
                               create_encryptor(encryptor))
            closer.watch(r)
            If is_outgoing Then
                connector.connect(r)
            Else
                accepter.listen(r)
            End If
            Return True
        End If
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal endpoint As IPEndPoint,
                                  ByVal connecting_timeout_ms As Int64,
                                  ByVal send_rate_sec As Int32,
                                  ByVal response_timeout_ms As Int64,
                                  ByVal receive_rate_sec As Int32,
                                  ByVal max_connecting As Int32,
                                  ByVal max_connected As Int32,
                                  ByVal no_delay As Boolean,
                                  ByVal max_lifetime_ms As Int64,
                                  ByVal is_outgoing As Boolean,
                                  ByVal enable_keepalive As Boolean,
                                  ByVal first_keepalive_ms As UInt32,
                                  ByVal keepalive_interval_ms As UInt32,
                                  ByVal zipper As String,
                                  ByVal encryptor As String,
                                  ByRef r As powerpoint) As Boolean
        If endpoint Is Nothing Then
            Return False
        ElseIf Not is_outgoing AndAlso
               Not endpoint.Address().Equals(IPAddress.Any) AndAlso
               Not endpoint.Address().Equals(IPAddress.IPv6Any) Then
            Return False
        Else
            Return create(token,
                          If(is_outgoing, Convert.ToString(endpoint.Address()), Nothing),
                          CUShort(endpoint.Port()),
                          (endpoint.AddressFamily() = Sockets.AddressFamily.InterNetwork),
                          connecting_timeout_ms,
                          send_rate_sec,
                          response_timeout_ms,
                          receive_rate_sec,
                          max_connecting,
                          max_connected,
                          no_delay,
                          max_lifetime_ms,
                          is_outgoing,
                          enable_keepalive,
                          first_keepalive_ms,
                          keepalive_interval_ms,
                          zipper,
                          encryptor,
                          r)
        End If
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal endpoint As IPEndPoint,
                                  ByVal connecting_timeout_ms As Int64,
                                  ByVal send_rate_sec As Int32,
                                  ByVal response_timeout_ms As Int64,
                                  ByVal receive_rate_sec As Int32,
                                  ByVal max_connecting As Int32,
                                  ByVal max_connected As Int32,
                                  ByVal no_delay As Boolean,
                                  ByVal max_lifetime_ms As Int64,
                                  ByVal is_outgoing As Boolean,
                                  ByVal enable_keepalive As Boolean,
                                  ByVal first_keepalive_ms As UInt32,
                                  ByVal keepalive_interval_ms As UInt32,
                                  ByVal zipper As String,
                                  ByVal encryptor As String) As powerpoint
        Dim r As powerpoint = Nothing
        assert(create(token,
                      endpoint,
                      connecting_timeout_ms,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      is_outgoing,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor,
                      r))
        Return r
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal port As UInt16,
                                  ByRef r As powerpoint,
                                  Optional ByVal send_rate_sec As Int32 = _
                                        default_value.send_rate_sec,
                                  Optional ByVal response_timeout_ms As Int64 = _
                                        default_value.response_timeout_ms,
                                  Optional ByVal receive_rate_sec As Int32 = _
                                        default_value.receive_rate_sec,
                                  Optional ByVal max_connecting As Int32 = _
                                        default_value.max_connecting,
                                  Optional ByVal max_connected As Int32 = _
                                        default_value.incoming.max_connected,
                                  Optional ByVal no_delay As Boolean = _
                                        default_value.no_delay,
                                  Optional ByVal max_lifetime_ms As Int64 = _
                                        default_value.incoming.max_lifetime_ms,
                                  Optional ByVal enable_keepalive As Boolean = _
                                        default_value.enable_keepalive,
                                  Optional ByVal first_keepalive_ms As UInt32 = _
                                        default_value.first_keepalive_ms,
                                  Optional ByVal keepalive_interval_ms As UInt32 = _
                                        default_value.keepalive_interval_ms,
                                  Optional ByVal zipper As String = _
                                        default_value.zipper,
                                  Optional ByVal encryptor As String = _
                                        default_value.encryptor) _
                                 As Boolean
        Return create(token,
                      Nothing,
                      port,
                      True,
                      npos,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      False,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor,
                      r)
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal port As UInt16,
                                  Optional ByVal send_rate_sec As Int32 = _
                                        default_value.send_rate_sec,
                                  Optional ByVal response_timeout_ms As Int64 = _
                                        default_value.response_timeout_ms,
                                  Optional ByVal receive_rate_sec As Int32 = _
                                        default_value.receive_rate_sec,
                                  Optional ByVal max_connecting As Int32 = _
                                        default_value.max_connecting,
                                  Optional ByVal max_connected As Int32 = _
                                        default_value.incoming.max_connected,
                                  Optional ByVal no_delay As Boolean = _
                                        default_value.no_delay,
                                  Optional ByVal max_lifetime_ms As Int64 = _
                                        default_value.incoming.max_lifetime_ms,
                                  Optional ByVal enable_keepalive As Boolean = _
                                        default_value.enable_keepalive,
                                  Optional ByVal first_keepalive_ms As UInt32 = _
                                        default_value.first_keepalive_ms,
                                  Optional ByVal keepalive_interval_ms As UInt32 = _
                                        default_value.keepalive_interval_ms,
                                  Optional ByVal zipper As String = _
                                        default_value.zipper,
                                  Optional ByVal encryptor As String = _
                                        default_value.encryptor) _
                                 As powerpoint
        Dim r As powerpoint = Nothing
        assert(create(token,
                      port,
                      r,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor))
        Return r
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal remote_endpoint As IPEndPoint,
                                  ByRef r As powerpoint,
                                  Optional ByVal connecting_timeout_ms As Int64 = _
                                        default_value.outgoing.connecting_timeout_ms,
                                  Optional ByVal send_rate_sec As Int32 = _
                                        default_value.send_rate_sec,
                                  Optional ByVal response_timeout_ms As Int64 = _
                                        default_value.response_timeout_ms,
                                  Optional ByVal receive_rate_sec As Int32 = _
                                        default_value.receive_rate_sec,
                                  Optional ByVal max_connecting As Int32 = _
                                        default_value.max_connecting,
                                  Optional ByVal max_connected As Int32 = _
                                        default_value.outgoing.max_connected,
                                  Optional ByVal no_delay As Boolean = _
                                        default_value.no_delay,
                                  Optional ByVal max_lifetime_ms As Int64 = _
                                        default_value.outgoing.max_lifetime_ms,
                                  Optional ByVal enable_keepalive As Boolean = _
                                        default_value.enable_keepalive,
                                  Optional ByVal first_keepalive_ms As UInt32 = _
                                        default_value.first_keepalive_ms,
                                  Optional ByVal keepalive_interval_ms As UInt32 = _
                                        default_value.keepalive_interval_ms,
                                  Optional ByVal zipper As String = _
                                        default_value.zipper,
                                  Optional ByVal encryptor As String = _
                                        default_value.encryptor) _
                                 As Boolean
        Return create(token,
                      remote_endpoint,
                      connecting_timeout_ms,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      True,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor,
                      r)
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal remote_endpoint As IPEndPoint,
                                  Optional ByVal connecting_timeout_ms As Int64 = _
                                        default_value.outgoing.connecting_timeout_ms,
                                  Optional ByVal send_rate_sec As Int32 = _
                                        default_value.send_rate_sec,
                                  Optional ByVal response_timeout_ms As Int64 = _
                                        default_value.response_timeout_ms,
                                  Optional ByVal receive_rate_sec As Int32 = _
                                        default_value.receive_rate_sec,
                                  Optional ByVal max_connecting As Int32 = _
                                        default_value.max_connecting,
                                  Optional ByVal max_connected As Int32 = _
                                        default_value.outgoing.max_connected,
                                  Optional ByVal no_delay As Boolean = _
                                        default_value.no_delay,
                                  Optional ByVal max_lifetime_ms As Int64 = _
                                        default_value.outgoing.max_lifetime_ms,
                                  Optional ByVal enable_keepalive As Boolean = _
                                        default_value.enable_keepalive,
                                  Optional ByVal first_keepalive_ms As UInt32 = _
                                        default_value.first_keepalive_ms, _
                                  Optional ByVal keepalive_interval_ms As UInt32 = _
                                        default_value.keepalive_interval_ms,
                                  Optional ByVal zipper As String = _
                                        default_value.zipper,
                                  Optional ByVal encryptor As String = _
                                        default_value.encryptor) _
                                 As powerpoint
        Dim r As powerpoint = Nothing
        assert(create(token,
                      remote_endpoint,
                      r,
                      connecting_timeout_ms,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor))
        Return r
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal remote_address As String,
                                  ByVal remote_port As UInt16,
                                  ByRef r As powerpoint,
                                  Optional ByVal connecting_timeout_ms As Int64 = _
                                        default_value.outgoing.connecting_timeout_ms,
                                  Optional ByVal send_rate_sec As Int32 = _
                                        default_value.send_rate_sec,
                                  Optional ByVal response_timeout_ms As Int64 = _
                                        default_value.response_timeout_ms,
                                  Optional ByVal receive_rate_sec As Int32 = _
                                        default_value.receive_rate_sec,
                                  Optional ByVal max_connecting As Int32 = _
                                        default_value.max_connecting,
                                  Optional ByVal max_connected As Int32 = _
                                        default_value.outgoing.max_connected,
                                  Optional ByVal no_delay As Boolean = _
                                        default_value.no_delay,
                                  Optional ByVal max_lifetime_ms As Int64 = _
                                        default_value.outgoing.max_lifetime_ms,
                                  Optional ByVal ipv4 As Boolean = _
                                        default_value.ipv4,
                                  Optional ByVal enable_keepalive As Boolean = _
                                        default_value.enable_keepalive,
                                  Optional ByVal first_keepalive_ms As UInt32 = _
                                        default_value.first_keepalive_ms,
                                  Optional ByVal keepalive_interval_ms As UInt32 = _
                                        default_value.keepalive_interval_ms,
                                  Optional ByVal zipper As String = _
                                        default_value.zipper,
                                  Optional ByVal encryptor As String = _
                                        default_value.encryptor) _
                                 As Boolean
        Return create(token,
                      remote_address,
                      remote_port,
                      ipv4,
                      connecting_timeout_ms,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      True,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor,
                      r)
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal remote_address As String,
                                  ByVal remote_port As UInt16,
                                  Optional ByVal connecting_timeout_ms As Int64 = _
                                        default_value.outgoing.connecting_timeout_ms,
                                  Optional ByVal send_rate_sec As Int32 = _
                                        default_value.send_rate_sec,
                                  Optional ByVal response_timeout_ms As Int64 = _
                                        default_value.response_timeout_ms,
                                  Optional ByVal receive_rate_sec As Int32 = _
                                        default_value.receive_rate_sec,
                                  Optional ByVal max_connecting As Int32 = _
                                        default_value.max_connecting,
                                  Optional ByVal max_connected As Int32 = _
                                        default_value.outgoing.max_connected,
                                  Optional ByVal no_delay As Boolean = _
                                        default_value.no_delay,
                                  Optional ByVal max_lifetime_ms As Int64 = _
                                        default_value.outgoing.max_lifetime_ms,
                                  Optional ByVal ipv4 As Boolean = _
                                        default_value.ipv4,
                                  Optional ByVal enable_keepalive As Boolean = _
                                        default_value.enable_keepalive,
                                  Optional ByVal first_keepalive_ms As UInt32 = _
                                        default_value.first_keepalive_ms,
                                  Optional ByVal keepalive_interval_ms As UInt32 = _
                                        default_value.keepalive_interval_ms,
                                  Optional ByVal zipper As String = _
                                        default_value.zipper,
                                  Optional ByVal encryptor As String = _
                                        default_value.encryptor) _
                                 As powerpoint
        Dim r As powerpoint = Nothing
        assert(create(token,
                      remote_address,
                      remote_port,
                      r,
                      connecting_timeout_ms,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      ipv4,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor))
        Return r
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal host_or_ip As String,
                                  ByVal port As String,
                                  ByVal ipv4 As String,
                                  ByVal connecting_timeout_ms As String,
                                  ByVal send_rate_sec As String,
                                  ByVal response_timeout_ms As String,
                                  ByVal receive_rate_sec As String,
                                  ByVal max_connecting As String,
                                  ByVal max_connected As String,
                                  ByVal no_delay As String,
                                  ByVal max_lifetime_ms As String,
                                  ByVal is_outgoing As String,
                                  ByVal enable_keepalive As String,
                                  ByVal first_keepalive_ms As String,
                                  ByVal keepalive_interval_ms As String,
                                  ByVal zipper As String,
                                  ByVal encryptor As String,
                                  ByRef r As powerpoint) As Boolean
        Return create(token,
                      host_or_ip,
                      port.to_uint16(),
                      ipv4.to_bool(default_value.ipv4),
                      connecting_timeout_ms.to_int64(default_value.outgoing.connecting_timeout_ms),
                      send_rate_sec.to_int32(default_value.send_rate_sec),
                      response_timeout_ms.to_int64(default_value.response_timeout_ms),
                      receive_rate_sec.to_int32(default_value.receive_rate_sec),
                      max_connecting.to_int32(default_value.max_connecting),
                      max_connected.to_int32(default_value.outgoing.max_connected),
                      no_delay.to_bool(default_value.no_delay),
                      max_lifetime_ms.to_int64(default_value.outgoing.max_lifetime_ms),
                      is_outgoing.to_bool(Not String.IsNullOrEmpty(host_or_ip)),
                      enable_keepalive.to_bool(default_value.enable_keepalive),
                      first_keepalive_ms.to_uint32(default_value.first_keepalive_ms),
                      keepalive_interval_ms.to_uint32(default_value.keepalive_interval_ms),
                      zipper,
                      encryptor,
                      r)
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal host_or_ip As String,
                                  ByVal port As String,
                                  ByVal ipv4 As String,
                                  ByVal connecting_timeout_ms As String,
                                  ByVal send_rate_sec As String,
                                  ByVal response_timeout_ms As String,
                                  ByVal receive_rate_sec As String,
                                  ByVal max_connecting As String,
                                  ByVal max_connected As String,
                                  ByVal no_delay As String,
                                  ByVal max_lifetime_ms As String,
                                  ByVal is_outgoing As String,
                                  ByVal enable_keepalive As String,
                                  ByVal first_keepalive_ms As String,
                                  ByVal keepalive_interval_ms As String,
                                  ByVal zipper As String,
                                  ByVal encryptor As String) As powerpoint
        Dim r As powerpoint = Nothing
        assert(create(token,
                      host_or_ip,
                      port,
                      ipv4,
                      connecting_timeout_ms,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      is_outgoing,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor,
                      r))
        Return r
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal remote_address As String,
                                  ByVal remote_port As String,
                                  ByRef r As powerpoint,
                                  ByVal connecting_timeout_ms As String,
                                  ByVal send_rate_sec As String,
                                  ByVal response_timeout_ms As String,
                                  ByVal receive_rate_sec As String,
                                  ByVal max_connecting As String,
                                  ByVal max_connected As String,
                                  ByVal no_delay As String,
                                  ByVal max_lifetime_ms As String,
                                  ByVal ipv4 As String,
                                  ByVal enable_keepalive As String,
                                  ByVal first_keepalive_ms As String,
                                  ByVal keepalive_interval_ms As String,
                                  ByVal zipper As String,
                                  ByVal encryptor As String) As Boolean
        Return create(token,
                      remote_address,
                      remote_port,
                      ipv4,
                      connecting_timeout_ms,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      Convert.ToString(True),
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor,
                      r)
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal remote_address As String,
                                  ByVal remote_port As String,
                                  ByVal connecting_timeout_ms As String,
                                  ByVal send_rate_sec As String,
                                  ByVal response_timeout_ms As String,
                                  ByVal receive_rate_sec As String,
                                  ByVal max_connecting As String,
                                  ByVal max_connected As String,
                                  ByVal no_delay As String,
                                  ByVal max_lifetime_ms As String,
                                  ByVal ipv4 As String,
                                  ByVal enable_keepalive As String,
                                  ByVal first_keepalive_ms As String,
                                  ByVal keepalive_interval_ms As String,
                                  ByVal zipper As String,
                                  ByVal encryptor As String) As powerpoint
        Dim r As powerpoint = Nothing
        assert(create(token,
                      remote_address,
                      remote_port,
                      r,
                      connecting_timeout_ms,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      ipv4,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor))
        Return r
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal port As String,
                                  ByRef r As powerpoint,
                                  ByVal send_rate_sec As String,
                                  ByVal response_timeout_ms As String,
                                  ByVal receive_rate_sec As String,
                                  ByVal max_connecting As String,
                                  ByVal max_connected As String,
                                  ByVal no_delay As String,
                                  ByVal max_lifetime_ms As String,
                                  ByVal enable_keepalive As String,
                                  ByVal first_keepalive_ms As String,
                                  ByVal keepalive_interval_ms As String,
                                  ByVal zipper As String,
                                  ByVal encryptor As String) As Boolean
        Return create(token,
                      Nothing,
                      port,
                      Nothing,
                      Nothing,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      Convert.ToString(False),
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor,
                      r)
    End Function

    Public Shared Function create(ByVal token As String,
                                  ByVal port As String,
                                  ByVal send_rate_sec As String,
                                  ByVal response_timeout_ms As String,
                                  ByVal receive_rate_sec As String,
                                  ByVal max_connecting As String,
                                  ByVal max_connected As String,
                                  ByVal no_delay As String,
                                  ByVal max_lifetime_ms As String,
                                  ByVal enable_keepalive As String,
                                  ByVal first_keepalive_ms As String,
                                  ByVal keepalive_interval_ms As String,
                                  ByVal zipper As String,
                                  ByVal encryptor As String) As powerpoint
        Dim r As powerpoint = Nothing
        assert(create(token,
                      port,
                      r,
                      send_rate_sec,
                      response_timeout_ms,
                      receive_rate_sec,
                      max_connecting,
                      max_connected,
                      no_delay,
                      max_lifetime_ms,
                      enable_keepalive,
                      first_keepalive_ms,
                      keepalive_interval_ms,
                      zipper,
                      encryptor))
        Return r
    End Function
End Class
